//! 日志配置模块
//!
//! 本模块提供了基于 `tracing` 的日志配置功能，支持同时输出到控制台和文件。
//! 文件日志按日期自动切分，且支持不同级别的过滤策略。
//!
//! # 特性
//! - 📝 控制台输出：INFO 及以上级别，带颜色和时间戳
//! - 💾 文件输出：ERROR 级别，按天切分，无颜色格式
//! - ⏰ RFC3339 标准时间格式
//! - 🚀 非阻塞写入，高性能
//!
//! # 使用示例
//!
//! ## 基本使用
//! ```
//! use common_service::log_helper::setup_logging;
//! use tracing::{info, error};
//!
//! fn main() {
//!     // 必须在程序开始处初始化日志
//!     let _guard = setup_logging();
//!
//!     info!("应用程序启动");
//!     error!("这是一个错误信息");
//! }
//! ```
//!
//! ## 在二进制项目中
//! ```no_run
//! use common_service::log_helper::setup_logging;
//! use tracing::{info, instrument};
//!
//! #[instrument]
//! fn process_data() {
//!     info!("处理数据中...");
//! }
//!
//! fn main() {
//!     let _guard = setup_logging();
//!
//!     info!("开始执行任务");
//!     process_data();
//!     info!("任务完成");
//! }
//! ```
//!
//! # 注意事项
//! - 返回的 `WorkerGuard` 必须保持生命周期直到程序结束
//! - 日志文件将保存在 `./logs/` 目录下，文件名为 `app.YYYY-MM-DD.log`
//! - 控制台输出 INFO 级别，文件只记录 ERROR 级别

use time::OffsetDateTime;
use time::macros::format_description;
use tracing_appender::rolling;
use tracing_subscriber::{
    Layer, Registry, filter::LevelFilter, fmt, fmt::format::Writer, fmt::time::FormatTime,
    layer::SubscriberExt, util::SubscriberInitExt,
};
struct MyLocalTime;
impl FormatTime for MyLocalTime {
    fn format_time(&self, w: &mut Writer<'_>) -> std::fmt::Result {
        let now = OffsetDateTime::now_local().unwrap();
        let format = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
        write!(w, "{}", now.format(&format).unwrap())
    }
}

//tracing_appender::non_blocking 创建了一个非阻塞的日志写入器，WorkerGuard 就是这个后台线程的守护者或所有者。所以要保证这个WorkGuard不会提前drop
//1.应用程序主线程把日志消息发送到channel中
//2.后台创建一个专用的线程，会从channel的另一端接收消息，写入控制台或者文件等中
pub fn setup_logging() -> tracing_appender::non_blocking::WorkerGuard {
    // 设置日志输出到文件且按日期切分
    let file_appender = rolling::daily("logs", "app.log");
    let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
    // 配置控制台输出层
    let console_layer = fmt::layer()
        .with_writer(std::io::stdout)
        .with_timer(MyLocalTime)
        .with_level(true)
        .with_ansi(false) //关闭彩色日志  线上不支持
        .with_filter(LevelFilter::INFO);
    // 配置文件输出层
    let file_layer = fmt::layer()
        .with_writer(non_blocking)
        .with_timer(MyLocalTime)
        .with_level(true)
        .with_ansi(false) //去掉控制台颜色
        .with_filter(LevelFilter::ERROR);
    // 组合所有层级并初始化
    Registry::default()
        .with(console_layer)
        .with(file_layer)
        .init();
    guard
}
